package io.wongxd.solution.compose.custom.views.touch_bar

import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import io.wongxd.solution.compose.custom.views.res.Res
import kotlin.math.roundToInt

/**
 * effect : 星星选择和展示控件
 *          Star bar
 *
 * @param starValue 当前选中的星星数量
 *                  Value of star with selected
 * @param onStarValueChange 选中的星星数量改变的回调
 *                          Callback of the [starValue] change
 * @param modifier 修饰
 * @param maxStar 最大星星数
 *                Star max value
 * @param starPainter 未选中的星星的图片
 *                    [Painter] of star
 * @param starSelectPainter 选中的星星的图片
 *                          [Painter] of star with selected
 * @param starSize 星星的大小
 *                 Size of star
 * @param margin 星星间的间距
 *               Distance between stars
 * @param orientation 滑动的方向
 *                    Scroll orientation
 * @param userEnable 用户是否可以滑动,等于false时用户滑动无反应,但代码可以执行翻页
 *                   Whether the user can scroll
 * @param onTouchUpEvent 手指抬起事件
 *                       Callback of touch up event
 */
@Composable
fun StarBar(
    starValue: Int,
    onStarValueChange: (Int) -> Unit,
    modifier: Modifier = Modifier,
    maxStar: Int = 5,
    starPainter: Painter = Res.getStarPainter(),
    starSelectPainter: Painter = Res.getStarSelectPainter(),
    starSize: Dp = 16.dp,
    margin: Dp = 3.dp,
    orientation: Orientation = Orientation.Horizontal,
    userEnable: Boolean = true,
    onTouchUpEvent: (() -> Unit)? = null,
) {
    val singleStarPercentage by remember(maxStar) {
        mutableStateOf(1f / maxStar)
    }
    val starValueNumber by rememberUpdatedState(newValue = starValue)
    var progress by remember(maxStar) {
        mutableStateOf(starValueNumber * singleStarPercentage)
    }
    BasicsProgressBar(
        progress = progress,
        onProgressChange = {
            progress = it
            val star = (progress / singleStarPercentage).roundToInt()
            if (star != starValueNumber)
                onStarValueChange(star)
        },
        modifier = modifier,
        orientation = orientation,
        userEnable = userEnable,
        onTouchUpEvent = onTouchUpEvent,
    ) {
        @Composable
        fun Star() {
            repeat(maxStar) { index ->
                Image(
                    painter = if (starValue > index) starSelectPainter else starPainter,
                    contentDescription = "star",
                    modifier = Modifier
                        .size(starSize)
                        .let {
                            if (userEnable)
                                it.clickable(remember { MutableInteractionSource() }, null) {
                                    onStarValueChange(index + 1)
                                    onTouchUpEvent?.invoke()
                                }
                            else
                                it
                        },
                )
                if (index < maxStar - 1)
                    Spacer(modifier = Modifier.size(margin))
            }
        }

        if (orientation == Orientation.Horizontal)
            Row {
                Star()
            }
        else
            Column {
                Star()
            }
    }
}